//
//  MEController.m
//  MapEditor
//
//  Created by Eric on 3/3/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "MEController.h"
#import "MEDefine.h"
#import "MEEditShapeLayer.h"
#import "BBPackAction.h"
#import "HelloWorldLayer.h"
#import "MEEditStageLayer.h"
#import "BBUtil.h"
#import "MELayer.h"
#import "MEUtil.h"
#import "RegexKitLite.h"

static MEController* g_controller;

@interface MEController(hide)
-(void)setLayerParam:(MEBox2dLayer*)layer;
-(void)resetPrototypeBody:(MEPrototype*)prototype;
@end

@implementation MEController
@synthesize dataFilePath;
@synthesize glView;
@synthesize prototypeTabView;
@synthesize prototypeTabPopBtn;

@synthesize layersPane;
@synthesize stageTabView;
@synthesize stageTabPopBtn;


@synthesize testBuildBtn;
@synthesize testStopBtn;
@synthesize testRestBtn;

@synthesize drawEdgeField;
//@synthesize mapCollectionView;


-(void)dealloc
{
    self.dataFilePath = nil;
    self.glView = nil;
    self.prototypeTabView = nil;
    self.prototypeTabPopBtn = nil;
    
    self.layersPane = nil;
    self.stageTabView = nil;
    self.stageTabPopBtn = nil;
    
    self.testBuildBtn = nil;
    self.testRestBtn = nil;
    self.testStopBtn = nil;
    
    self.drawEdgeField = nil;
    //self.mapCollectionView = nil;
    
    self.window = nil;
    [[CCDirector sharedDirector] end];
    [super dealloc];
}

-(void)windowDidLoad{
    [super windowDidLoad];
    CCDirectorMac *director = (CCDirectorMac*) [CCDirector sharedDirector];
	[director setDisplayFPS:YES];	
	[director setOpenGLView:glView];
    
	// EXPERIMENTAL stuff.
	// 'Effects' don't work correctly when autoscale is turned on.
	// Use kCCDirectorResize_NoScale if you don't want auto-scaling.
	[director setResizeMode:kCCDirectorResize_AutoScale];
	
	// Enable "moving" mouse event. Default no.
	[self.window setAcceptsMouseMovedEvents:NO];
	
	MEEditStageLayer* layer = [MEEditStageLayer layer];
    ((MEGLView*)glView).editStageLayer = layer;
    
	[director runWithScene:[layer scene]];
    //[[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];
    
    g_controller = self;
   
    CGSize wsize = [director winSize];
    CGFloat w = glWField.floatValue;
    CGFloat h = glHField.floatValue;
    CGFloat scale = glSField.floatValue;
    layer.position = ccp((wsize.width - w)/2 * scale, (wsize.height - h)/2  * scale);
    layer.layerSize = CGSizeMake(w, h);
    layer.scale = scale;    
    
    [self performSelector:@selector(load) withObject:nil afterDelay:0.1f];
}
-(void)load{
    if (dataFilePath) {
        [self openFile:[NSURL URLWithString:[NSString stringWithFormat:@"file://localhost%@", dataFilePath]]];
    }else{
        NSArray* tabViewItems = prototypeTabView.tabViewItems;
        for(NSTabViewItem* tabViewItem in tabViewItems){
            [prototypeTabView removeTabViewItem:tabViewItem];
        }
        [prototypeTabPopBtn removeAllItems];
        for (NSTabViewItem* item in stageTabView.tabViewItems) {
            [stageTabView removeTabViewItem:item];
        }
        [self addStage:nil];
    }
}

+ (MEController*)instance
{
    return g_controller;
}

-(IBAction)prototypeFieldChanged:(id)sender
{
    NSControl *field = sender;
    MEPrototype* prototype = [self selectedPrototype];
    CGFloat value = field.floatValue;
    switch (field.tag) {
        case T_EDIT_PROTOTYPE_CLASSNAME:
        {
            prototype.className = [sender stringValue];
            break;
        }
        case T_EDIT_PROTOTYPE_FILETYPE:
        {
            NSInteger selected = [sender selectedColumn];
            prototype.fileType = selected;
            if (prototype.sid == glView.editStageLayer.draggedSprite.prototypeParam.sid) {
                NSString* fileType = [[prototypeFileTypeField cellAtRow:0 column:selected] title];
                sptFileTypeField.stringValue = fileType;
            }
            break;
        }
            /*
        case T_EDIT_PROTOTYPE_SCALE:
        {
            prototype.scale = value;
            
            MEScene* scene = [MEScene scene];
            MEEditShapeLayer* layer = (MEEditShapeLayer*)scene.layer;
            if ([layer isKindOfClass:[MEEditShapeLayer class]]) {
                layer.spt.scale = value;
            }
            break;
        }     
             */
        case T_EDIT_PROTOTYPE_BODY_BOX2D:
        {
            BOOL checked = prototypeBox2dField.integerValue!=0;
            prototype.isBox2dObj = checked;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_D:
        {
            prototype.density = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_F:
        {
            prototype.friction = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_R:
        {
            prototype.restitution = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_TYPE:
        {
            NSInteger selected = [sender selectedColumn];
            prototype.bodyType = selected;
            break;
        }  
        case T_EDIT_PROTOTYPE_BODY_SHAPE:
        {
            NSInteger selected = [sender selectedColumn];      
            prototype.shapeIndex = selected;
            break;
        }   
        case T_EDIT_PROTOTYPE_BODY_SOFT_ISSOFT:
        {
            prototype.isSoftBody = value!=0;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_SEMENTSNUM:
        {
            prototype.segmentsNum = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_FRQUENCY_OUT:
        {
            prototype.frequencyHzOut = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_FRQUENCY_IN:
        {
            prototype.frequencyHzIn = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_DAMPING_OUT:
        {
            prototype.dampingRatioOut = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_DAMPING_IN:
        {
            prototype.dampingRatioIn = value;
            break;
        } 
        case T_EDIT_PROTOTYPE_BODY_SOFT_INNERRATEX:
        {
            prototype.innerRateX = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_INNERRATEY:
        {
            prototype.innerRateY = value;
            break;
        } 
            
        default:
            break;
    }
    [self refreshPrototypeInfo];
}


-(IBAction)spriteFieldChanged:(id)sender
{
    NSControl *field = sender;
    CGFloat value = [field floatValue];
    MEEditStageLayer* layer = glView.editStageLayer;
    MEEditStageSprite* spt = layer.draggedSprite;

    if (![spt parent]) {
        return;
    }
    
    switch (field.tag) {
        case T_EDIT_PROTOTYPE_CLASSNAME:
        {
            spt.prototypeParam.className = [sender stringValue];
            break;
        }
        case T_EDIT_SPT_X:
        {
            spt.positionForBody = ccp(value, spt.positionForBody.y);
            break;
        }
        case T_EDIT_SPT_Y:
        {
            spt.positionForBody = ccp(spt.positionForBody.x, value);
            break;
        }   
        case T_EDIT_SPT_FLIPX:
        {
            spt.flipX = value;
            break;
        }
        case T_EDIT_SPT_FLIPY:
        {
            spt.flipY = value;
            break;
        } 
        case T_EDIT_SPT_R:
        {
            spt.rotation = value;
            
            break;
        }  
        case T_EDIT_PROTOTYPE_SCALE:
        {
            spt.scale = value;         
            break;
        }                
        case T_EDIT_PROTOTYPE_BODY_BOX2D:
        {
            spt.prototypeParam.isBox2dObj = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_D:
        {
            spt.prototypeParam.density = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_F:
        {
            spt.prototypeParam.friction = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_R:
        {
            spt.prototypeParam.restitution = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_TYPE:
        {
            NSInteger selected = [sender selectedColumn];
            spt.prototypeParam.bodyType = selected;    
            break;
        }  
        case T_EDIT_PROTOTYPE_BODY_SHAPE:
        {
            NSInteger selected = [sender selectedColumn];          
            spt.prototypeParam.shapeIndex = selected;
            break;
        }   
        case T_EDIT_PROTOTYPE_BODY_SOFT_ISSOFT:
        {
            spt.prototypeParam.isSoftBody = value!=0;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_SEMENTSNUM:
        {
            spt.prototypeParam.segmentsNum = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_FRQUENCY_OUT:
        {
            spt.prototypeParam.frequencyHzOut = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_FRQUENCY_IN:
        {
            spt.prototypeParam.frequencyHzIn = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_DAMPING_OUT:
        {
            spt.prototypeParam.dampingRatioOut = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_DAMPING_IN:
        {
            spt.prototypeParam.dampingRatioIn = value;
            break;
        }   
        case T_EDIT_PROTOTYPE_BODY_SOFT_INNERRATEX:
        {
            spt.prototypeParam.innerRateX = value;
            break;
        }
        case T_EDIT_PROTOTYPE_BODY_SOFT_INNERRATEY:
        {
            spt.prototypeParam.innerRateY = value;
            break;
        } 
        case T_EDIT_SPT_TAG0:
        {
            spt.tag0 = value;
            break;
        }
        case T_EDIT_SPT_TAG1:
        {
            spt.tag1 = value;
            break;
        }
        case T_EDIT_SPT_TAG2:
        {
            spt.tag2 = value;
            break;
        }
        case T_EDIT_SPT_TAG3:
        {
            spt.tag3 = value;
            break;
        }
        default:
            break;
    }
    [self refreshSpriteInfo:spt];
    [spt resetBody:layer.world];
}

-(IBAction)editShapeBtnClicked:(id)sender
{
    [testBuildBtn setEnabled:NO];
    [testRestBtn setEnabled:NO];
    [testStopBtn setEnabled:NO];
    [prototypeSField setEnabled:NO];
    [prototypeEditShapeBtn setEnabled:NO];
    
    MEPrototype* prototype = [self selectedPrototype];
    if (prototype) {
        BBPackAction* done = [BBPackFuncD action:self func:@selector(editShapeDone:) param:[NSNumber numberWithBool:YES]];
        BBPackAction* cancel = [BBPackFuncD action:self func:@selector(editShapeDone:) param:[NSNumber numberWithBool:NO]];
        MEEditShapeLayer* layer = [MEEditShapeLayer layer:prototype done:done cancel:cancel];
        [self setLayerParam:layer];
        
        [[CCDirector sharedDirector] replaceScene:[layer scene]];
    }
}
-(void)editShapeDone:(NSNumber*)done{
    [testBuildBtn setEnabled:YES];
    [testRestBtn setEnabled:NO];
    [testStopBtn setEnabled:NO];
    [prototypeSField setEnabled:YES];
    [prototypeEditShapeBtn setEnabled:YES];
    
    if ([done boolValue]) {
        MEEditShapeLayer* layer = (MEEditShapeLayer*)((MEScene*)[[CCDirector sharedDirector] runningScene]).layer;
        MEPrototype* prototype = [self selectedPrototype];
        prototype.shapeCenter = layer.bodyCenter;
        prototype.shapes = layer.shapes;
    }   
    [self setLayerParam:glView.editStageLayer];
    [[CCDirector sharedDirector] replaceScene:[glView.editStageLayer scene]];
}

-(IBAction)lock:(id)sender{
    NSInteger value = [sender integerValue];
    MEScene* scene = [MEScene scene];
    MEBox2dLayer* layer = scene.layer;
    if (value) {
        layer.moveMode = YES;
    }else{
        layer.moveMode = NO;
    }
}

-(IBAction)addLayer:(id)sender
{
    MEEditStageLayer* layer = (MEEditStageLayer*)([[MEScene scene] layer]);
    if ([layer isKindOfClass:[MEEditStageLayer class]]) {
        [layer addLayer];
        [layersPane setContent:layer.layers];
    }
}
-(IBAction)removeLayer:(id)sender
{
    MEEditStageLayer* layer = (MEEditStageLayer*)([[MEScene scene] layer]);
    if ([layer isKindOfClass:[MEEditStageLayer class]]) {
        MEEditStageSubLayer* subLayer = [self selectedLayer];
        if (subLayer) {
            [layer removeLayer:subLayer];
        }
        [layersPane setContent:layer.layers];
    }
    
}

-(IBAction)moveLayer:(id)sender
{
    NSInteger tag = [sender tag];
    MEEditStageLayer* layer = (MEEditStageLayer*)([[MEScene scene] layer]);
    if ([layer isKindOfClass:[MEEditStageLayer class]]) {
        MEEditStageSubLayer* subLayer = [self selectedLayer];
        if (subLayer) {
            NSInteger newIndex = [layer moveLayer:subLayer way:tag];
            [layersPane setContent:layer.layers];
            [layersPane setSelectionIndexes:[NSIndexSet indexSetWithIndex:newIndex]];
        }       
    }
}
-(IBAction)changeLayerName:(id)sender
{
    NSTextField* textField = sender;
    [textField setEditable:NO];
}
-(IBAction)removePrototypeGroup:(id)sender
{
    NSTabViewItem* item = prototypeTabView.selectedTabViewItem;
    if (item) {
        NSMenu* rightClick =  [ [NSMenu alloc] initWithTitle:@"RightClick"];
        NSMenuItem* remove = [[[NSMenuItem  alloc] init] autorelease];
        [remove setTitle:@"Remove Group"];
        [remove setRepresentedObject:item];
        [remove setAction:@selector(removePrototypeTabViewItem:)];
        [remove setTarget:self];
        [rightClick addItem:remove];
        
        NSRect frame = [(NSButton *)sender frame];
        NSPoint menuOrigin = [[(NSButton *)sender superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height+20)
                                                                   toView:nil];
        
        NSEvent *event =  [NSEvent mouseEventWithType:NSLeftMouseDown
                                             location:menuOrigin
                                        modifierFlags:NSLeftMouseDownMask // 0x100
                                            timestamp:nil
                                         windowNumber:[[(NSButton *)sender window] windowNumber]
                                              context:[[(NSButton *)sender window] graphicsContext]
                                          eventNumber:0
                                           clickCount:1
                                             pressure:1];
        
        [NSMenu popUpContextMenu:rightClick withEvent:event forView:sender];
    }    
}
-(void)removePrototypeTabViewItem:(id)obj{
    NSInteger index = [prototypeTabView indexOfTabViewItem:[obj representedObject]];
    [prototypeTabView removeTabViewItem:[obj representedObject]];
    
    [prototypeTabPopBtn removeItemAtIndex:index];
}

-(IBAction)build:(id)sender
{
    NSControl* btn = sender;
    if (btn.tag==1) {
        NSArray* param =  [glView.editStageLayer toParam];        
        MELayer* layer = [MELayer layer];
        [self setLayerParam:layer];        
        [layer loadDict:[param objectAtIndex:glView.editStageLayer.curStageIndex]];
        
        if (worldEdgeField.integerValue!=0) {
            [layer buildEdge];
        }
        
        [[CCDirector sharedDirector] replaceScene:[layer scene]];
        
        [prototypeEditShapeBtn setEnabled:NO];
        [testBuildBtn setEnabled:NO];
        [testStopBtn setEnabled:YES];
        [testRestBtn setEnabled:YES];
    }else{
        [self setLayerParam:glView.editStageLayer];
        [[CCDirector sharedDirector] replaceScene:[glView.editStageLayer scene]];
        
        NSInteger selected = [prototypeSField selectedColumn];
       
        [prototypeEditShapeBtn setEnabled:YES && selected==BODY_S_POLYGON];
        [testBuildBtn setEnabled:YES];
        [testStopBtn setEnabled:NO];
        [testRestBtn setEnabled:NO];
    }

}


-(IBAction)saveFile:(id)sender
{
    NSString* fileName = @"mapeditor";
    if (self.dataFilePath) {
        fileName = [[self.dataFilePath lastPathComponent] stringByDeletingPathExtension];
    }
    NSSavePanel *panel = [NSSavePanel savePanel];
    [panel setAllowedFileTypes:[NSArray arrayWithObject:@"me"]];
    
    [panel setNameFieldStringValue:fileName];
    NSInteger clicked = [panel runModal];
    if (clicked == NSFileHandlingPanelOKButton) {
        NSURL *url = [panel URL];
        self.dataFilePath = [url path];
    }else{
        return;
    }
    if (dataFilePath) {       
        NSString* imagesPath = [dataFilePath stringByAppendingPathComponent:@"images"];
        
        NSFileWrapper* mainDirectory = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        
        //write images
        NSFileWrapper* imagesDirectory = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        [imagesDirectory setPreferredFilename:@"images"];
        [mainDirectory addFileWrapper:imagesDirectory];
        
        NSArray* tabViewItems = prototypeTabView.tabViewItems;
        for(NSTabViewItem* tabViewItem in tabViewItems){
            NSString* catName = tabViewItem.label;
            NSFileWrapper* imageDirectory = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
            [imageDirectory setPreferredFilename:catName];
            
            
            NSCollectionView* collection = [tabViewItem.view collection];
            NSArray* prototypes = collection.content;
            for(MEPrototype* prototype in prototypes){
                [imageDirectory addFileWithPath:prototype.filePath];
            }
            
            [imagesDirectory addFileWrapper:imageDirectory];
        }
        
        
        
        
        NSMutableDictionary* prototypeCats = [NSMutableDictionary dictionaryWithCapacity:[tabViewItems count]];
        for(NSTabViewItem* tabViewItem in tabViewItems){
            NSString* catName = tabViewItem.label;
            NSCollectionView* collection = [tabViewItem.view collection];
            NSArray* prototypes = collection.content;
            NSMutableArray* prototypeParams = [NSMutableArray arrayWithCapacity:[prototypes count]];
            for(MEPrototype* protoype in prototypes){
                NSString* filePath = protoype.filePath;
                NSString* fileName = [filePath lastPathComponent];
                filePath = [[imagesPath stringByAppendingPathComponent:catName] stringByAppendingPathComponent:fileName];
                protoype.filePath = filePath;
                NSDictionary* param = [protoype toDict];
                
                
                [prototypeParams addObject:param];
            }
            [prototypeCats setObject:prototypeParams forKey:catName];
        }
        
        
        
        
        
        NSArray* stages = [glView.editStageLayer toParam];
        for (NSDictionary* stageParam in stages) {
            NSArray* subLayersParam = [stageParam objectForKey:@"layers"];
            for (NSDictionary* layerParam in subLayersParam) {  
                NSArray* sptParams = [layerParam objectForKey:@"sprites"];                
                for (NSMutableDictionary* sptParam in sptParams) {
                    NSInteger prototypeId = [sptParam intValue:@"prototype" defaultVal:0];
                    MEPrototype* protoype = [[MEPrototypeMgr instance] prototypeWithSid:prototypeId];
                    [sptParam setObject:protoype.filePath forKey:@"filePath"];                    
                }
            }
        }
        
        BOOL showShape = debugShapeField.integerValue != 0;
        BOOL showJoint = debugJointField.integerValue != 0;
        BOOL showAABB = debugAABBField.integerValue != 0;
        BOOL showPair = debugPairField.integerValue != 0;
        BOOL showMassCenter = debugMassCenterField.integerValue != 0;
        BOOL worldEdge = worldEdgeField.integerValue != 0;
        
        NSInteger layerSizeW = glWField.integerValue;
        NSInteger layerSizeH = glHField.integerValue;
        CGFloat layerScale = glSField.floatValue;
        
        NSMutableDictionary* exportParam = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                            prototypeCats, @"prototype", 
                                            stages, @"stages",
                                            [NSNumber numberWithBool:showShape], @"showShape",
                                            [NSNumber numberWithBool:showJoint], @"showJoint",
                                            [NSNumber numberWithBool:showAABB], @"showAABB",
                                            [NSNumber numberWithBool:showPair], @"showPair",
                                            [NSNumber numberWithBool:showMassCenter], @"showMassCenter",  
                                            [NSNumber numberWithBool:worldEdge], @"worldEdge",
                                            [NSString stringWithFormat:@"{x=%d;y=%d}", layerSizeW, layerSizeH], @"layerSize",
                                            [NSNumber numberWithFloat:layerScale], @"layerScale",
                                            nil];
        
        // [exportParam writeToFile:dataFilePath atomically:YES];  
        
       
        
        //write config
        NSString * error;
        NSData * data = [NSPropertyListSerialization dataFromPropertyList:exportParam format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        [mainDirectory addRegularFileWithContents:data preferredFilename:@"config.plist"];
        
        
        [mainDirectory writeToFile:dataFilePath atomically:YES updateFilenames:YES];
    }

}


-(IBAction)exportFile:(id)sender
{
    NSString* fileName = @"mapeditor";
    if (self.dataFilePath) {
        fileName = [[self.dataFilePath lastPathComponent] stringByDeletingPathExtension];
    }
    NSSavePanel *panel = [NSSavePanel savePanel];
    
    [panel setNameFieldStringValue:fileName];
    NSInteger clicked = [panel runModal];
    if (clicked == NSFileHandlingPanelOKButton) {
        NSURL *url = [panel URL];
        self.dataFilePath = [url path];
        if ([dataFilePath isMatchedByRegex:@".+//me"]) {
            self.dataFilePath = [dataFilePath substringToIndex:[dataFilePath length]-3];
        }
    }else{
        return;
    }
    CGFloat iPadOffx = 32;
    CGFloat iPadOffy = 64;
    
    if (dataFilePath) {
        NSFileWrapper* mainDirectory = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        
        NSArray* stages = [glView.editStageLayer toParam];        
        NSMutableArray* stagesIP3 = [NSMutableArray arrayWithCapacity:[stages count]];
        NSMutableArray* stagesIP4 = [NSMutableArray arrayWithCapacity:[stages count]];
        NSMutableArray* stagesIPad2 = [NSMutableArray arrayWithCapacity:[stages count]];
        NSMutableArray* stagesIPad3 = [NSMutableArray arrayWithCapacity:[stages count]];
        NSMutableArray* stagesMac = [NSMutableArray arrayWithCapacity:[stages count]];
        
        for (NSDictionary* stageParam in stages) {
            NSMutableDictionary* stageParamIP3 = [NSMutableDictionary dictionaryWithDictionary:stageParam];
            NSMutableDictionary* stageParamIP4 = [NSMutableDictionary dictionaryWithDictionary:stageParam];
            NSMutableDictionary* stageParamIPad2 = [NSMutableDictionary dictionaryWithDictionary:stageParam];
            NSMutableDictionary* stageParamIPad3 = [NSMutableDictionary dictionaryWithDictionary:stageParam];
            NSMutableDictionary* stageParamMac = [NSMutableDictionary dictionaryWithDictionary:stageParam];
            
            CGFloat ptmRatio = [stageParam floatValue:@"ptmRatio" defaultVal:PTM_RATIO];
            CGFloat ptmRatioIP3 = ptmRatio / 2;
            CGFloat ptmRatioIP4 = ptmRatio;
            CGFloat ptmRatioIPad2 = ptmRatio;
            CGFloat ptmRatioIPad3 = ptmRatio * 2;
            CGFloat ptmRatioMac = ptmRatio;
            
            [stageParamIP3 setObject:[NSNumber numberWithFloat:ptmRatioIP3] forKey:@"ptmRatio"];
            [stageParamIP4 setObject:[NSNumber numberWithFloat:ptmRatioIP4] forKey:@"ptmRatio"];
            [stageParamIPad2 setObject:[NSNumber numberWithFloat:ptmRatioIPad2] forKey:@"ptmRatio"];
            [stageParamIPad3 setObject:[NSNumber numberWithFloat:ptmRatioIPad3] forKey:@"ptmRatio"];
            [stageParamMac setObject:[NSNumber numberWithFloat:ptmRatioMac] forKey:@"ptmRatio"];
            
            NSPoint gravity = NSPointFromString([stageParam objectForKey:@"gravity"]); 
            [stageParamIP3 setObject:[NSString stringWithFormat:@"{%f,%f}", gravity.x, gravity.y] forKey:@"gravity"];
            [stageParamIP4 setObject:[NSString stringWithFormat:@"{%f,%f}", gravity.x, gravity.y] forKey:@"gravity"];
            [stageParamIPad2 setObject:[NSString stringWithFormat:@"{%f,%f}", gravity.x, gravity.y] forKey:@"gravity"];
            [stageParamIPad3 setObject:[NSString stringWithFormat:@"{%f,%f}", gravity.x, gravity.y] forKey:@"gravity"];
            [stageParamMac setObject:[NSString stringWithFormat:@"{%f,%f}", gravity.x, gravity.y] forKey:@"gravity"];
            
            
            
            NSArray* subLayersParam = [stageParam objectForKey:@"layers"];
            NSMutableArray* subLayersParamIP3 = [NSMutableArray array];
            NSMutableArray* subLayersParamIP4 = [NSMutableArray array];
            NSMutableArray* subLayersParamIPad2 = [NSMutableArray array];
            NSMutableArray* subLayersParamIPad3 = [NSMutableArray array];
            NSMutableArray* subLayersParamMac = [NSMutableArray array];
            
            for (NSDictionary* layerParam in subLayersParam) {                
                NSMutableDictionary* layerParamIP3 = [NSMutableDictionary dictionary];
                NSMutableDictionary* layerParamIP4 = [NSMutableDictionary dictionary];
                NSMutableDictionary* layerParamIPad2 = [NSMutableDictionary dictionary];
                NSMutableDictionary* layerParamIPad3 = [NSMutableDictionary dictionary];
                NSMutableDictionary* layerParamMac = [NSMutableDictionary dictionary];
                
                NSString* name = [layerParam objectForKey:@"name"];
                [layerParamIP3 setObject:name forKey:@"name"];
                [layerParamIP4 setObject:name forKey:@"name"];
                [layerParamIPad2 setObject:name forKey:@"name"];
                [layerParamIPad3 setObject:name forKey:@"name"];
                [layerParamMac setObject:name forKey:@"name"];
                
                
                NSArray* sptParams = [layerParam objectForKey:@"sprites"];
                NSMutableArray* sptParamsIP3 = [NSMutableArray array];
                NSMutableArray* sptParamsIP4 = [NSMutableArray array];
                NSMutableArray* sptParamsIPad2 = [NSMutableArray array];
                NSMutableArray* sptParamsIPad3 = [NSMutableArray array];
                NSMutableArray* sptParamsMac = [NSMutableArray array];
                
                for (NSDictionary* sptParam in sptParams) {
                    NSPoint pos = NSPointFromString([sptParam objectForKey:@"pos"]); 
                    NSMutableDictionary* sptParamIP3 = [NSMutableDictionary dictionaryWithDictionary:sptParam];
                    NSMutableDictionary* sptParamIP4 = [NSMutableDictionary dictionaryWithDictionary:sptParam];
                    NSMutableDictionary* sptParamIPad2 = [NSMutableDictionary dictionaryWithDictionary:sptParam];
                    NSMutableDictionary* sptParamIPad3 = [NSMutableDictionary dictionaryWithDictionary:sptParam];
                    NSMutableDictionary* sptParamMac = [NSMutableDictionary dictionaryWithDictionary:sptParam];
                    
                    [sptParamIP3 removeObjectForKey:@"filePath"];
                    [sptParamIP4 removeObjectForKey:@"filePath"];
                    [sptParamIPad2 removeObjectForKey:@"filePath"];
                    [sptParamIPad3 removeObjectForKey:@"filePath"];
                    [sptParamMac removeObjectForKey:@"filePath"];
                    
                    [sptParamIP3 setObject:[NSString stringWithFormat:@"{%f,%f}", pos.x/2, pos.y/2] forKey:@"pos"];
                    [sptParamIP4 setObject:[NSString stringWithFormat:@"{%f,%f}", pos.x, pos.y] forKey:@"pos"];
                    [sptParamIPad2 setObject:[NSString stringWithFormat:@"{%f,%f}", pos.x + iPadOffx, pos.y + iPadOffy] forKey:@"pos"];
                    [sptParamIPad3 setObject:[NSString stringWithFormat:@"{%f,%f}",2 * (pos.x + iPadOffx), 2 * (pos.y + iPadOffy)] forKey:@"pos"];
                    [sptParamMac setObject:[NSString stringWithFormat:@"{%f,%f}", pos.x, pos.y] forKey:@"pos"];
                    
                    NSArray* shapes = [sptParam objectForKey:@"shapes"];
                    if (shapes) {
                        NSPoint center = NSPointFromString([sptParam objectForKey:@"shapeCenter"]); 
                        NSString* centerStr = [NSString stringWithFormat:@"{%f,%f}", center.x, center.y];
                        [sptParamIP3 setObject:centerStr forKey:@"shapeCenter"];
                        [sptParamIP4 setObject:centerStr forKey:@"shapeCenter"];
                        [sptParamIPad2 setObject:centerStr forKey:@"shapeCenter"];
                        [sptParamIPad3 setObject:centerStr forKey:@"shapeCenter"];
                        [sptParamMac setObject:centerStr forKey:@"shapeCenter"];
                        
                        NSMutableArray* newShapesIP = [NSMutableArray arrayWithCapacity:[shapes count]];    
                        NSMutableArray* newShapesIP4 = [NSMutableArray arrayWithCapacity:[shapes count]];    
                        NSMutableArray* newShapesIPad2 = [NSMutableArray arrayWithCapacity:[shapes count]];    
                        NSMutableArray* newShapesIPad3 = [NSMutableArray arrayWithCapacity:[shapes count]];    
                        NSMutableArray* newShapesMac = [NSMutableArray arrayWithCapacity:[shapes count]];    
                        
                        for (NSDictionary* cparam in shapes) {
                            NSMutableDictionary* newCparamIP = [NSMutableDictionary dictionaryWithDictionary:cparam];
                            NSMutableDictionary* newCparamIP4 = [NSMutableDictionary dictionaryWithDictionary:cparam];
                            NSMutableDictionary* newCparamIPad2 = [NSMutableDictionary dictionaryWithDictionary:cparam];
                            NSMutableDictionary* newCparamIPad3 = [NSMutableDictionary dictionaryWithDictionary:cparam];
                            NSMutableDictionary* newCparamMac = [NSMutableDictionary dictionaryWithDictionary:cparam];
                            
                            NSArray* points = [cparam objectForKey:@"points"];
                            NSMutableArray* newPointsIP = [NSMutableArray arrayWithCapacity:[points count]];
                            NSMutableArray* newPointsIP4 = [NSMutableArray arrayWithCapacity:[points count]];
                            NSMutableArray* newPointsIPad2 = [NSMutableArray arrayWithCapacity:[points count]];
                            NSMutableArray* newPointsIPad3 = [NSMutableArray arrayWithCapacity:[points count]];
                            NSMutableArray* newPointsMac = [NSMutableArray arrayWithCapacity:[points count]];
                            
                            
                            for (NSString* ps in points) {
                                NSPoint p = NSPointFromString(ps);
                                NSString* newPIP = [NSString stringWithFormat:@"{%f,%f}", p.x/2, p.y/2];
                                NSString* newPIP4 = [NSString stringWithFormat:@"{%f,%f}", p.x, p.y];
                                NSString* newPIPad2 = [NSString stringWithFormat:@"{%f,%f}", p.x, p.y];
                                NSString* newPIPad3 = [NSString stringWithFormat:@"{%f,%f}", p.x*2, p.y*2];
                                NSString* newPMac = [NSString stringWithFormat:@"{%f,%f}", p.x, p.y];
                                
                                [newPointsIP addObject:newPIP];
                                [newPointsIP4 addObject:newPIP4];
                                [newPointsIPad2 addObject:newPIPad2];
                                [newPointsIPad3 addObject:newPIPad3];                               
                                [newPointsMac addObject:newPMac];                               
                                
                            }            
                            [newCparamIP setObject:newPointsIP forKey:@"points"];
                            [newCparamIP4 setObject:newPointsIP4 forKey:@"points"];
                            [newCparamIPad2 setObject:newPointsIPad2 forKey:@"points"];
                            [newCparamIPad3 setObject:newPointsIPad3 forKey:@"points"];
                            [newCparamMac setObject:newPointsMac forKey:@"points"];
                            
                            
                            [newShapesIP addObject:newCparamIP];
                            [newShapesIP4 addObject:newCparamIP4];
                            [newShapesIPad2 addObject:newCparamIPad2];
                            [newShapesIPad3 addObject:newCparamIPad3];                            
                            [newShapesMac addObject:newCparamMac];                            
                            
                        }
                        [sptParamIP3 setObject:newShapesIP forKey:@"shapes"];
                        [sptParamIP4 setObject:newShapesIP4 forKey:@"shapes"];
                        [sptParamIPad2 setObject:newShapesIPad2 forKey:@"shapes"];
                        [sptParamIPad3 setObject:newShapesIPad3 forKey:@"shapes"];
                        [sptParamMac setObject:newShapesMac forKey:@"shapes"];
                        
                    }
                    
                    [sptParamsIP3 addObject:sptParamIP3];
                    [sptParamsIP4 addObject:sptParamIP4];
                    [sptParamsIPad2 addObject:sptParamIPad2];
                    [sptParamsIPad3 addObject:sptParamIPad3]; 
                    [sptParamsMac addObject:sptParamMac]; 
                    
                }
                
                [layerParamIP3 setObject:sptParamsIP3 forKey:@"sprites"];
                [layerParamIP4 setObject:sptParamsIP4 forKey:@"sprites"];
                [layerParamIPad2 setObject:sptParamsIPad2 forKey:@"sprites"];
                [layerParamIPad3 setObject:sptParamsIPad3 forKey:@"sprites"];
                [layerParamMac setObject:sptParamsMac forKey:@"sprites"];
                
                [subLayersParamIP3 addObject:layerParamIP3];
                [subLayersParamIP4 addObject:layerParamIP4];
                [subLayersParamIPad2 addObject:layerParamIPad2];
                [subLayersParamIPad3 addObject:layerParamIPad3];   
                [subLayersParamMac addObject:layerParamMac];   
                
            }
            [stageParamIP3 setObject:subLayersParamIP3 forKey:@"layers"];
            [stageParamIP4 setObject:subLayersParamIP4 forKey:@"layers"];
            [stageParamIPad2 setObject:subLayersParamIPad2 forKey:@"layers"];
            [stageParamIPad3 setObject:subLayersParamIPad3 forKey:@"layers"];
            [stageParamMac setObject:subLayersParamMac forKey:@"layers"];
            
            [stagesIP3 addObject:stageParamIP3];
            [stagesIP4 addObject:stageParamIP4];
            [stagesIPad2 addObject:stageParamIPad2];
            [stagesIPad3 addObject:stageParamIPad3];   
            [stagesMac addObject:stageParamMac];   
            
        }
        NSDictionary* exportIP3 = [NSDictionary dictionaryWithObjectsAndKeys:stagesIP3, @"stages", nil];
        NSDictionary* exportIP4 = [NSDictionary dictionaryWithObjectsAndKeys:stagesIP4, @"stages", nil];
        NSDictionary* exportIPad2 = [NSDictionary dictionaryWithObjectsAndKeys:stagesIPad2, @"stages", nil];
        NSDictionary* exportIPad3 = [NSDictionary dictionaryWithObjectsAndKeys:stagesIPad3, @"stages", nil];
        NSDictionary* exportMac = [NSDictionary dictionaryWithObjectsAndKeys:stagesMac, @"stages", nil];
        
        
        //write config
        NSString * error;
        NSData * dataIP3 = [NSPropertyListSerialization dataFromPropertyList:exportIP3 format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        NSData * dataIP4 = [NSPropertyListSerialization dataFromPropertyList:exportIP4 format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        NSData * dataIPad2 = [NSPropertyListSerialization dataFromPropertyList:exportIPad2 format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        NSData * dataIPad3 = [NSPropertyListSerialization dataFromPropertyList:exportIPad3 format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        NSData * dataMac = [NSPropertyListSerialization dataFromPropertyList:exportMac format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
        
        
        [mainDirectory addRegularFileWithContents:dataIP3 preferredFilename:@"meconfig.plist"];
        [mainDirectory addRegularFileWithContents:dataIP4 preferredFilename:@"meconfig-hd.plist"];
        [mainDirectory addRegularFileWithContents:dataIPad2 preferredFilename:@"meconfig-ipad.plist"];
        [mainDirectory addRegularFileWithContents:dataIPad3 preferredFilename:@"meconfig-ipadhd.plist"];     
        [mainDirectory addRegularFileWithContents:dataMac preferredFilename:@"meconfig-mac.plist"];     
        
        //write images
        NSFileWrapper* fileImagesDirectoryIP3 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* fileImagesDirectoryIP4 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* fileImagesDirectoryIPad2 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* fileImagesDirectoryIPad3 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* fileImagesDirectoryMac = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        
        
        NSFileWrapper* tpImagesDirectoryIP3 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tpImagesDirectoryIP4 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tpImagesDirectoryIPad2 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tpImagesDirectoryIPad3 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tpImagesDirectoryMac = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        
        
        NSFileWrapper* tileImagesDirectoryIP3 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tileImagesDirectoryIP4 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tileImagesDirectoryIPad2 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tileImagesDirectoryIPad3 = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        NSFileWrapper* tileImagesDirectoryMac = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
        
        [tpImagesDirectoryIP3 setPreferredFilename:@"tpImages"];
        [tpImagesDirectoryIP4 setPreferredFilename:@"tpImages-hd"];
        [tpImagesDirectoryIPad2 setPreferredFilename:@"tpImages-ipad"];
        [tpImagesDirectoryIPad3 setPreferredFilename:@"tpImages-ipadhd"];
        [tpImagesDirectoryMac setPreferredFilename:@"tpImages-mac"];
        
        [fileImagesDirectoryIP3 setPreferredFilename:@"fileImages"];
        [fileImagesDirectoryIP4 setPreferredFilename:@"fileImages-hd"];
        [fileImagesDirectoryIPad2 setPreferredFilename:@"fileImages-ipad"];
        [fileImagesDirectoryIPad3 setPreferredFilename:@"fileImages-ipadhd"];
        [fileImagesDirectoryMac setPreferredFilename:@"fileImages-mac"];

        [tileImagesDirectoryIP3 setPreferredFilename:@"tileImages"];
        [tileImagesDirectoryIP4 setPreferredFilename:@"tileImages-hd"];
        [tileImagesDirectoryIPad2 setPreferredFilename:@"tileImages-ipad"];
        [tileImagesDirectoryIPad3 setPreferredFilename:@"tileImages-ipadhd"];
        [tileImagesDirectoryMac setPreferredFilename:@"tileImages-mac"];
        
        NSArray* tabViewItems = prototypeTabView.tabViewItems;
        for(NSTabViewItem* tabViewItem in tabViewItems){
           
            NSCollectionView* collection = [tabViewItem.view collection];
            NSArray* prototypes = collection.content;
            for(MEPrototype* prototype in prototypes){
                NSFileWrapper* imagesDirectoryIP3;
                NSFileWrapper* imagesDirectoryIP4;
                NSFileWrapper* imagesDirectoryIPad2;
                NSFileWrapper* imagesDirectoryIPad3;
                NSFileWrapper* imagesDirectoryMac;
                
                NSString* fileIP3 = [prototype.filePath lastPathComponent];
                NSString* fileIP4 = fileIP3;
                NSString* fileIPad2 = fileIP3;
                NSString* fileIPad3 = fileIP3;
                NSString* fileMac = fileIP3;
                
                if (prototype.fileType==0) {
                    imagesDirectoryIP3 = tpImagesDirectoryIP3;
                    imagesDirectoryIP4 = tpImagesDirectoryIP4;
                    imagesDirectoryIPad2 = tpImagesDirectoryIPad2;
                    imagesDirectoryIPad3 = tpImagesDirectoryIPad3;
                    imagesDirectoryMac = tpImagesDirectoryMac;
                    
                }else {
                    fileIP4 = [NSString stringWithFormat:@"%@-hd.%@", [fileIP3 stringByDeletingPathExtension], [fileIP4 pathExtension]];
                    fileIPad2 = [NSString stringWithFormat:@"%@-ipad.%@", [fileIP3 stringByDeletingPathExtension], [fileIPad2 pathExtension]];
                    fileIPad3 = [NSString stringWithFormat:@"%@-ipadhd.%@", [fileIP3 stringByDeletingPathExtension], [fileIPad3 pathExtension]];
                    fileMac = [NSString stringWithFormat:@"%@.%@", [fileIP3 stringByDeletingPathExtension], [fileMac pathExtension]];
                    
                    if (prototype.fileType==1) {
                        imagesDirectoryIP3 = fileImagesDirectoryIP3;
                        imagesDirectoryIP4 = fileImagesDirectoryIP4;
                        imagesDirectoryIPad2 = fileImagesDirectoryIPad2;
                        imagesDirectoryIPad3 = fileImagesDirectoryIPad3;
                        imagesDirectoryMac = fileImagesDirectoryMac;
                        
                    }else{
                        imagesDirectoryIP3 = tileImagesDirectoryIP3;
                        imagesDirectoryIP4 = tileImagesDirectoryIP4;
                        imagesDirectoryIPad2 = tileImagesDirectoryIPad2;
                        imagesDirectoryIPad3 = tileImagesDirectoryIPad3;
                        imagesDirectoryMac = tileImagesDirectoryMac;
                        
                    }
                }
                
                NSImage* imageIP3 = [[[NSImage alloc] initWithContentsOfFile:prototype.filePath] autorelease];
                imageIP3 = [MEUtil resizeImage:imageIP3 scale:.5f];
                if (imageIP3) {
                    NSData *dataIP3 = [MEUtil imageToData:imageIP3 ext:[prototype.filePath pathExtension]];
                    [imagesDirectoryIP3 addRegularFileWithContents:dataIP3 preferredFilename:fileIP3];
                }
                
                
                NSImage* imageIP4 = [[[NSImage alloc] initWithContentsOfFile:prototype.filePath] autorelease];
                NSData *dataIP4 = [MEUtil imageToData:imageIP4 ext:[prototype.filePath pathExtension]];
                [imagesDirectoryIP4 addRegularFileWithContents:dataIP4 preferredFilename:fileIP4];
                
                NSImage* imageIPad2 = [[[NSImage alloc] initWithContentsOfFile:prototype.filePath] autorelease];
                NSData *dataIPad2 = [MEUtil imageToData:imageIPad2 ext:[prototype.filePath pathExtension]];
                [imagesDirectoryIPad2 addRegularFileWithContents:dataIPad2 preferredFilename:fileIPad2];
                
                NSImage* imageIPad3 = [[[NSImage alloc] initWithContentsOfFile:prototype.filePath] autorelease];
                imageIPad3 = [MEUtil resizeImage:imageIPad3 scale:2.f];
                NSData *dataIPad3 = [MEUtil imageToData:imageIPad3 ext:[prototype.filePath pathExtension]];
                [imagesDirectoryIPad3 addRegularFileWithContents:dataIPad3 preferredFilename:fileIPad3];
                
                
                NSImage* imageMac = [[[NSImage alloc] initWithContentsOfFile:prototype.filePath] autorelease];
                NSData *dataMac = [MEUtil imageToData:imageMac ext:[prototype.filePath pathExtension]];
                [imagesDirectoryMac addRegularFileWithContents:dataMac preferredFilename:fileMac];
            }
            
        }
        [mainDirectory addFileWrapper:tpImagesDirectoryIP3];
        [mainDirectory addFileWrapper:tpImagesDirectoryIP4];
        [mainDirectory addFileWrapper:tpImagesDirectoryIPad2];
        [mainDirectory addFileWrapper:tpImagesDirectoryIPad3];
        [mainDirectory addFileWrapper:tpImagesDirectoryMac];
        
        [mainDirectory addFileWrapper:fileImagesDirectoryIP3];
        [mainDirectory addFileWrapper:fileImagesDirectoryIP4];
        [mainDirectory addFileWrapper:fileImagesDirectoryIPad2];
        [mainDirectory addFileWrapper:fileImagesDirectoryIPad3];
        [mainDirectory addFileWrapper:fileImagesDirectoryMac];
        
        
        [mainDirectory addFileWrapper:tileImagesDirectoryIP3];
        [mainDirectory addFileWrapper:tileImagesDirectoryIP4];
        [mainDirectory addFileWrapper:tileImagesDirectoryIPad2];
        [mainDirectory addFileWrapper:tileImagesDirectoryIPad3];
        [mainDirectory addFileWrapper:tileImagesDirectoryMac];
        
        
        
        [mainDirectory writeToFile:dataFilePath atomically:YES updateFilenames:YES];
    }
}




-(IBAction)loadFile:(id)sender
{
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    [panel setCanChooseFiles:YES];
    [panel setCanChooseDirectories:NO];
    [panel setAllowsMultipleSelection:NO];
    NSInteger clicked = [panel runModal];
    if (clicked == NSFileHandlingPanelOKButton) {
        [[MEPrototypeMgr instance] removeAllPrototypes];
        for (NSURL *url in [panel URLs]) {
            [self openFile:url];
            break;
        }
    } 
}

-(void)openFile:(NSURL*)url{
    /*
    NSError * error;
    NSFileWrapper* mainDirectory = [[[NSFileWrapper alloc] initWithURL:url options:NSFileWrapperReadingImmediate error:&error] autorelease];
    NSDictionary* files = [mainDirectory fileWrappers];
    NSLog(@"files=%@", files);
    
    //read config
    NSString * errorDesc;
    NSFileWrapper* cfgDirectory = [files objectForKey:@"config.plist"];
    NSData* cfgData = [cfgDirectory regularFileContents];
    NSPropertyListFormat format;
    NSDictionary* exportParam  = [NSPropertyListSerialization propertyListFromData:cfgData 
                                     mutabilityOption:NSPropertyListImmutable 
                                               format:&format
                                     errorDescription:&errorDesc ];
    */
    NSString* urlPath = [url path];
    NSString* path = [urlPath stringByAppendingPathComponent:@"config.plist"];
    NSDictionary* exportParam  = [NSDictionary dictionaryWithContentsOfFile:path];
    
    NSString* imagesPath = [urlPath stringByAppendingPathComponent:@"images"];
    NSDictionary* prototypeCats = [exportParam objectForKey:@"prototype"];
    if (prototypeCats) {
        NSArray* tabViewItems = prototypeTabView.tabViewItems;
        for(NSTabViewItem* tabViewItem in tabViewItems){
            [prototypeTabView removeTabViewItem:tabViewItem];
        }
        [prototypeTabPopBtn removeAllItems];
        for (NSString* catName in prototypeCats) {
            
            NSTabViewItem* item = [[NSTabViewItem alloc] init]; 
            item.label = catName;
            
            NSArray* prototypeParams = [prototypeCats objectForKey:catName];
            NSMutableArray* prototypeList = [NSMutableArray arrayWithCapacity:[prototypeParams count]];
            for (NSDictionary* param in prototypeParams) {
                NSString* filePath = [param objectForKey:@"filePath"];
                NSString* fileName = [filePath lastPathComponent];
                filePath = [[imagesPath stringByAppendingPathComponent:catName] stringByAppendingPathComponent:fileName];
                NSMutableDictionary* newParam = [NSMutableDictionary dictionaryWithDictionary:param];
                [newParam setObject:filePath forKey:@"filePath"];
                MEPrototype *prototype = [[MEPrototypeMgr instance] dictToPrototype:newParam];
                [prototypeList addObject:prototype];
            }
            
            
            NSViewController *itemCtrl = [[NSViewController alloc] init];
            [NSBundle loadNibNamed:@"MEPrototypeCollection" owner: itemCtrl];            
            [((MEPrototypeTabItemView*)itemCtrl.view).collection setContent:prototypeList];
            
            item.view = itemCtrl.view;            
            [prototypeTabView addTabViewItem:item];
            
            [prototypeTabPopBtn addItemWithTitle:catName];
        }
    }
    
   
    
    
    NSDictionary* stages = [exportParam objectForKey:@"stages"];
    if (stages) {
        [glView.editStageLayer loadDict:stages];
        for (NSTabViewItem* item in stageTabView.tabViewItems) {
            [stageTabView removeTabViewItem:item];
        }
        [stageTabPopBtn removeAllItems];
        for (NSInteger i=0;i<[stages count];i++) {
            NSViewController *itemCtrl = [[[NSViewController alloc] init] autorelease];
            [NSBundle loadNibNamed:@"MEStageTabItemView" owner: itemCtrl]; 
            
            NSTabViewItem* item = [[NSTabViewItem alloc] init]; 
            item.label = [NSString stringWithFormat:@"%d", i+1];
            item.view = itemCtrl.view;            
            [stageTabView addTabViewItem:item];
            [stageTabPopBtn addItemWithTitle:item.label];
        }
    }
    
    
    debugShapeField.integerValue = [exportParam boolValue:@"showShape" defaultVal:debugShapeField.integerValue != 0];
    debugJointField.integerValue = [exportParam boolValue:@"showJoint" defaultVal:debugJointField.integerValue != 0];
    debugAABBField.integerValue = [exportParam boolValue:@"showAABB" defaultVal:debugAABBField.integerValue != 0];
    debugPairField.integerValue = [exportParam boolValue:@"showPair" defaultVal:debugPairField.integerValue != 0];
    debugMassCenterField.integerValue = [exportParam boolValue:@"showMassCenter" defaultVal:debugMassCenterField.integerValue != 0];
    worldEdgeField.integerValue = [exportParam boolValue:@"worldEdge" defaultVal:worldEdgeField.integerValue != 0];
    
    CGPoint p = NSPointToCGPoint(NSPointFromString([exportParam value:@"layerSize" 
                                                           defaultVal:[NSString stringWithFormat:@"@{x=%d;y=%d}", 
                                                                       glWField.integerValue, 
                                                                       glHField.integerValue]]));
    glWField.integerValue = p.x;
    glHField.integerValue = p.y;
    glSField.floatValue = [exportParam floatValue:@"layerScale" defaultVal:glSField.floatValue];
    
    
    [self refreshDebugInfo:[MEScene scene].layer];
} 



-(IBAction)addStage:(id)sender
{
    [glView.editStageLayer addStage];
    
    NSViewController *itemCtrl = [[[NSViewController alloc] init] autorelease];
    [NSBundle loadNibNamed:@"MEStageTabItemView" owner: itemCtrl]; 
    
    NSTabViewItem* item = [[[NSTabViewItem alloc] init] autorelease]; 
    item.label = [NSString stringWithFormat:@"%d",[glView.editStageLayer.stages count]];
    item.view = itemCtrl.view;            
    [stageTabView addTabViewItem:item];    
    
    [stageTabView selectTabViewItem:item];
    

    [layersPane setContent:glView.editStageLayer.layers];
    [layersPane setSelectionIndexes:[NSIndexSet indexSetWithIndex:0]];  
    
    [stageTabPopBtn addItemWithTitle:item.label];
    [stageTabPopBtn selectItemAtIndex:[stageTabView indexOfTabViewItem:item]];
}

-(IBAction)moveStage:(id)sender
{
    NSInteger tag = [sender tag];
    NSArray* items = stageTabView.tabViewItems;
    NSTabViewItem* item = stageTabView.selectedTabViewItem;
    NSInteger itemIndex = [items indexOfObject:item];
    NSInteger tgtIndex = itemIndex + tag;
    
    if (tgtIndex<0 || tgtIndex>=[items count]) {
        return;
    }
    NSTabViewItem* tgtItem = [stageTabView tabViewItemAtIndex:tgtIndex];
    [glView.editStageLayer moveStage:itemIndex tgt: tgtIndex];
    [stageTabView selectTabViewItem:tgtItem];
    
    [stageTabPopBtn selectItemAtIndex:[stageTabView indexOfTabViewItem:tgtItem]];
}

-(IBAction)removeStage:(id)sender
{
    NSTabViewItem* item = prototypeTabView.selectedTabViewItem;
    if (item) {
        NSMenu* rightClick =  [ [NSMenu alloc] initWithTitle:@"RightClick"];
        NSMenuItem* remove = [[[NSMenuItem  alloc] init] autorelease];
        [remove setTitle:@"Remove Stage"];
        [remove setRepresentedObject:item];
        [remove setAction:@selector(removeStageTabViewItem:)];
        [remove setTarget:self];
        [rightClick addItem:remove];
        
        NSRect frame = [(NSButton *)sender frame];
        NSPoint menuOrigin = [[(NSButton *)sender superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height+20)
                                                                   toView:nil];
        
        NSEvent *event =  [NSEvent mouseEventWithType:NSLeftMouseDown
                                             location:menuOrigin
                                        modifierFlags:NSLeftMouseDownMask // 0x100
                                            timestamp:nil
                                         windowNumber:[[(NSButton *)sender window] windowNumber]
                                              context:[[(NSButton *)sender window] graphicsContext]
                                          eventNumber:0
                                           clickCount:1
                                             pressure:1];
        
        [NSMenu popUpContextMenu:rightClick withEvent:event forView:sender];
    }    
}
-(void)removeStageTabViewItem:(id)obj{
    NSArray* items = stageTabView.tabViewItems;
    NSTabViewItem* item = stageTabView.selectedTabViewItem;
    NSInteger itemIndex = [items indexOfObject:item];
    for (NSTabViewItem* item in items) {
        [stageTabView removeTabViewItem:item];
    }
    [glView.editStageLayer removeStage:itemIndex];
    itemIndex = MIN(itemIndex, [glView.editStageLayer.stages count]-1);
    [glView.editStageLayer changeStage:itemIndex];
    
    
    for (NSInteger i=0; i<[glView.editStageLayer.stages count]; i++) {
        NSViewController *itemCtrl = [[[NSViewController alloc] init] autorelease];
        [NSBundle loadNibNamed:@"MEStageTabItemView" owner: itemCtrl]; 
        
        NSTabViewItem* item = [[[NSTabViewItem alloc] init] autorelease]; 
        item.label = [NSString stringWithFormat:@"%d",i+1];
        item.view = itemCtrl.view;            
        [stageTabView addTabViewItem:item];    
        
        if (i==itemIndex) {
            [stageTabView selectTabViewItem:item];
        }        
    }
    
    [stageTabPopBtn removeItemAtIndex:itemIndex];
}



-(IBAction)glFieldChanged:(id)sender
{
    MEScene *scene = [MEScene scene];
    MEBox2dLayer* layer = scene.layer;
    
    NSControl *field = sender;
    CGFloat value = [field floatValue];
    if (field.tag==T_EDIT_GLVIEW_S) {
        layer.scale = value;
        glSField.floatValue = value;
        glSlider.floatValue = value;
    }else if(field.tag==T_EDIT_GLVIEW_W){
        CGSize size = layer.layerSize;
        size.width = value;
        layer.layerSize = size;
    }else if(field.tag==T_EDIT_GLVIEW_H){
        CGSize size = layer.layerSize;
        size.height = value;
        layer.layerSize = size;
    }
}

-(IBAction)debugFieldChanged:(id)sender
{
    MEBox2dLayer* layer = [MEScene scene].layer;
    [self refreshDebugInfo:layer];    
}

-(IBAction)spriteReorder:(id)sender
{
    [glView.editStageLayer reorderSprite:[sender tag]];
}

-(void)refreshDebugInfo:(MEBox2dLayer*)layer{
    BOOL showShape = debugShapeField.integerValue != 0;
    BOOL showJoint = debugJointField.integerValue != 0;
    BOOL showAABB = debugAABBField.integerValue != 0;
    BOOL showPair = debugPairField.integerValue != 0;
    BOOL showMassCenter = debugMassCenterField.integerValue != 0;
    
    uint32 flags = 0;
    flags += showShape ? b2DebugDraw::e_shapeBit : 0;
    flags += showJoint ? b2DebugDraw::e_jointBit : 0;
    flags += showAABB ? b2DebugDraw::e_aabbBit : 0;
    flags += showPair ? b2DebugDraw::e_pairBit : 0;
	flags += showMassCenter ? b2DebugDraw::e_centerOfMassBit : 0;
    
    [layer setDebugFlags:flags];
    
    NSInteger layerSizeW = glWField.integerValue;
    NSInteger layerSizeH = glHField.integerValue;
    CGFloat layerScale = glSField.floatValue;
    
    layer.layerSize = CGSizeMake(layerSizeW, layerSizeH);
    layer.scale = layerScale;
    
}

-(void)refreshPrototypeInfo{
    MEPrototype* prototype = [self selectedPrototype];
    if (!prototype) {
        [prototypeClassField setEnabled:NO];
        [prototypeFileTypeField setEnabled:NO];
        //[prototypeSCField setEnabled:YES];
        //[prototypeSCSlider setEnabled:YES];
        
        [prototypeBox2dField setEnabled:NO];
        [prototypeDField setEnabled:NO];
        [prototypeFField setEnabled:NO];
        [prototypeRField setEnabled:NO];
        [prototypeTField setEnabled:NO];
        [prototypeSField setEnabled:NO];
        [prototypeEditShapeBtn setEnabled:NO];
        [prototypeSoftBodyBtn setEnabled:NO];
        
        [prototypeSoftNField setEnabled:NO];
        [prototypeSoftHzOutField setEnabled:NO];
        [prototypeSoftDpOutField setEnabled:NO];
        [prototypeSoftHzInField setEnabled:NO];
        [prototypeSoftDpInField setEnabled:NO];
        [prototypeSoftInnerRateXField setEnabled:NO];
        [prototypeSoftInnerRateYField setEnabled:NO];
        return;
    }
    prototypeClassField.stringValue = prototype.className?prototype.className:@"";
    [prototypeFileTypeField selectCellAtRow:0 column:prototype.fileType]; 
    prototypeBox2dField.integerValue = prototype.isBox2dObj;
    prototypeDField.floatValue = prototype.density;
    prototypeFField.floatValue = prototype.friction;
    prototypeRField.floatValue = prototype.restitution;
    //prototypeSCField.floatValue = prototype.scale;
    //prototypeSCSlider.floatValue = prototype.scale;
    [prototypeTField selectCellAtRow:0 column:prototype.bodyType];         
    [prototypeSField selectCellAtRow:0 column:prototype.shapeIndex];
    prototypeSoftInnerRateXField.floatValue = prototype.innerRateX;
    prototypeSoftInnerRateYField.floatValue = prototype.innerRateY;
    prototypeSoftBodyBtn.integerValue = prototype.isSoftBody;
    
    [prototypeClassField setEnabled:YES];
    [prototypeFileTypeField setEnabled:YES];
    //[prototypeSCField setEnabled:YES];
    //[prototypeSCSlider setEnabled:YES];
    
    [prototypeBox2dField setEnabled:YES];
    [prototypeDField setEnabled:prototype.isBox2dObj];
    [prototypeFField setEnabled:prototype.isBox2dObj];
    [prototypeRField setEnabled:prototype.isBox2dObj];
    [prototypeTField setEnabled:prototype.isBox2dObj];
    [prototypeSField setEnabled:prototype.isBox2dObj];
    [prototypeEditShapeBtn setEnabled:prototype.shapeIndex == BODY_S_POLYGON];
    [prototypeSoftBodyBtn setEnabled:prototype.isBox2dObj];
    
    [prototypeSoftNField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    [prototypeSoftHzOutField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    [prototypeSoftDpOutField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    [prototypeSoftHzInField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    [prototypeSoftDpInField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    [prototypeSoftInnerRateXField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    [prototypeSoftInnerRateYField setEnabled:prototype.isSoftBody && prototype.isBox2dObj];
    
}

-(void)refreshSpriteInfo:(MEEditStageSprite*)spt{
    if (spt) {
        sptClassField.stringValue = spt.prototypeParam.className;
        sptIDField.integerValue = spt.sid;

        NSString* fileType = [[prototypeFileTypeField cellAtRow:0 column:spt.fileType] title];
        sptFileTypeField.stringValue = fileType;
        
        sptXField.floatValue = spt.positionForBody.x;
        sptYField.floatValue = spt.positionForBody.y;
        
        sptFlipXField.integerValue = spt.prototypeParam.flipX;
        sptFlipYField.integerValue = spt.prototypeParam.flipY;
        
        
        sptRField.floatValue = spt.prototypeParam.rotation;
        sptRSlider.floatValue = spt.prototypeParam.rotation;
        
        sptSCField.floatValue = spt.prototypeParam.scale;
        sptSCSlider.floatValue = spt.prototypeParam.scale;
        
        sptBox2dField.integerValue = spt.prototypeParam.isBox2dObj;
        sptBodyDField.floatValue = spt.prototypeParam.density;
        sptBodyFField.floatValue = spt.prototypeParam.friction;
        sptBodyRField.floatValue = spt.prototypeParam.restitution;
        
        [sptBodyTField selectCellAtRow:0 column:spt.prototypeParam.bodyType];         
        [sptBodySField selectCellAtRow:0 column:spt.prototypeParam.shapeIndex];
        sptSoftBtn.integerValue = spt.prototypeParam.isSoftBody;
        sptSoftNField.integerValue = spt.prototypeParam.segmentsNum;
        sptSoftHzOutField.floatValue = spt.prototypeParam.frequencyHzOut;
        sptSoftHzInField.floatValue = spt.prototypeParam.frequencyHzIn;
        sptSoftDpOutField.floatValue = spt.prototypeParam.dampingRatioOut;
        sptSoftDpInField.floatValue = spt.prototypeParam.dampingRatioIn;
        sptSoftInnerRateXField.floatValue = spt.prototypeParam.innerRateX;
        sptSoftInnerRateYField.floatValue = spt.prototypeParam.innerRateY;
        
        sptTag0Field.integerValue = spt.tag0;
        sptTag1Field.integerValue = spt.tag1;
        sptTag2Field.integerValue = spt.tag2;
        sptTag3Field.integerValue = spt.tag3;
        
        
        [sptClassField setEnabled:YES];
        [sptXField setEnabled:YES];
        [sptYField setEnabled:YES];  
        [sptFlipXField setEnabled:YES];
        [sptFlipYField setEnabled:YES];  
        
        [sptRField setEnabled:YES];  
        [sptRSlider setEnabled:YES];
        [sptSCField setEnabled:YES];
        [sptSCSlider setEnabled:YES];
        
        [sptTag0Field setEnabled:YES];
        [sptTag1Field setEnabled:YES];  
        [sptTag2Field setEnabled:YES];  
        [sptTag3Field setEnabled:YES];
        
        [sptBox2dField setEnabled:YES];
        [sptBodyDField setEnabled:spt.prototypeParam.isBox2dObj];
        [sptBodyFField setEnabled:spt.prototypeParam.isBox2dObj];
        [sptBodyRField setEnabled:spt.prototypeParam.isBox2dObj];
        [sptBodyTField setEnabled:spt.prototypeParam.isBox2dObj];
        [sptBodySField setEnabled:spt.prototypeParam.isBox2dObj];
        [sptSoftBtn setEnabled:spt.prototypeParam.isBox2dObj];
        
        [sptSoftNField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        [sptSoftHzOutField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        [sptSoftDpOutField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        [sptSoftHzInField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        [sptSoftDpInField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        [sptSoftInnerRateXField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        [sptSoftInnerRateYField setEnabled:spt.prototypeParam.isSoftBody && spt.prototypeParam.isBox2dObj];
        
    }else{
        sptClassField.stringValue = @"";
        sptIDField.integerValue = 0;
        sptFileTypeField.stringValue =  @"";
        
        sptXField.floatValue = 0;
        sptYField.floatValue = 0;
        sptRField.floatValue = 0;
        sptRSlider.floatValue = 0;
                
        sptBox2dField.integerValue = 0;
        sptBodyDField.floatValue = 0;
        sptBodyFField.floatValue = 0;
        sptBodyRField.floatValue = 0;
        
        [sptBodyTField selectCellAtRow:0 column:0];         
        [sptBodySField selectCellAtRow:0 column:0];
        sptSoftBtn.integerValue = 0;
        sptSoftNField.integerValue = 0;
        sptSoftHzOutField.floatValue = 0;
        sptSoftHzInField.floatValue = 0;
        sptSoftDpOutField.floatValue = 0;
        sptSoftDpInField.floatValue = 0;
        
        sptTag0Field.integerValue = 0;
        sptTag1Field.integerValue = 1;
        sptTag2Field.integerValue = 2;
        sptTag3Field.integerValue = 3;

        
        [sptClassField setEnabled:NO];
        [sptXField setEnabled:NO];
        [sptYField setEnabled:NO]; 
        [sptRField setEnabled:NO];  
        [sptRSlider setEnabled:NO];  
        [sptSCField setEnabled:NO];
        [sptSCSlider setEnabled:NO];
        
        [sptTag0Field setEnabled:NO];
        [sptTag1Field setEnabled:NO];  
        [sptTag2Field setEnabled:NO];  
        [sptTag3Field setEnabled:NO];
        
        [sptBox2dField setEnabled:NO];
        [sptBodyDField setEnabled:NO];
        [sptBodyFField setEnabled:NO];
        [sptBodyRField setEnabled:NO];
        [sptBodyTField setEnabled:NO];
        [sptBodySField setEnabled:NO];
        [sptSoftBtn setEnabled:NO];
        
        [sptSoftNField setEnabled:NO];
        [sptSoftHzOutField setEnabled:NO];
        [sptSoftDpOutField setEnabled:NO];
        [sptSoftHzInField setEnabled:NO];
        [sptSoftDpInField setEnabled:NO];
        [sptSoftInnerRateXField setEnabled:NO];
        [sptSoftInnerRateYField setEnabled:NO];
        
    }
}

-(MEPrototype*)selectedPrototype{
    NSCollectionView* collection = [prototypeTabView.selectedTabViewItem.view collection];
    NSArray* content = collection.content;
    NSIndexSet* index = collection.selectionIndexes;
    NSInteger currentIndex = [index firstIndex];
    if (currentIndex != NSNotFound){
        MEPrototype* prototype = [content objectAtIndex:currentIndex];
        return prototype;
    }
    return nil;
}

-(MEEditStageSubLayer*)selectedLayer{
    NSArray* content = layersPane.content;
    NSIndexSet* index = layersPane.selectionIndexes;
    NSInteger currentIndex = [index firstIndex];
    if (currentIndex != NSNotFound&&currentIndex<[content count]){
        MEEditStageSubLayer* layer = [content objectAtIndex:currentIndex];
        return layer;
    }
    return nil;
}



-(void)setLayerParam:(MEBox2dLayer*)layer{
    MEBox2dLayer* curLayer = [MEScene scene].layer;
    layer.position = curLayer.position;
    layer.moveMode = curLayer.moveMode;
    [self refreshDebugInfo:layer];
}

@end
